Previous Book Contents Book Index Next

Inside Macintosh: Overview /
Chapter 4 - Events


Handling Events Outside the Main Event Loop

You'll notice that some types of events--for example, keyUp and mouseUp--are simply ignored by the main event loop defined in Listing 4-4. Key-up events are ignored because most applications don't need to know that a key was released, only that it was pressed. Similarly, you usually don't need to know when the mouse button was released, because you're more interested in knowing whether (and where) the mouse button was pressed. In certain cases, however, you will be interested in a mouse-up event. For example, if the user presses the mouse button while the cursor is in a window's close box but then moves the cursor outside the close box before releasing the mouse button, you don't want to handle the mouse-down event. (This is another good example of user-centered design: allowing users to change their minds.)

It might appear that a problem is lurking, because the main event loop defined in
Listing 4-4 ignores mouse-up events. How, then, can your application determine that the user released the mouse button when the cursor was outside of the close box? The answer is simple: the system software provides a routine, TrackGoAway, that you call in response to a user click in the close box. The TrackGoAway function tracks user actions involving the close box; it returns the Boolean value TRUE if the cursor is still inside the close box when the button is released and FALSE otherwise. Listing 4-5 illustrates how to call TrackGoAway.

Listing 4-5 Tracking mouse events in the close box

PROCEDURE DoGoAwayBox (myWindow: WindowPtr; mouseloc: Point);
BEGIN
   IF TrackGoAway(myWindow, mouseloc) THEN
      DoCloseWindow(myWindow);
END;
The TrackGoAway function exits only when the mouse button is released. Because it determines internally when that happens, your application doesn't need to.

The system software provides routines to handle the three main cases in which you need to track the mouse and determine if the cursor is in a particular location when the button is released. Here are the main routines you'll use:
Mouse-tracking routineAction
TrackBoxTrack the cursor in a window's zoom box
TrackControlTrack the cursor within a control
TrackGoAwayTrack the cursor in a window's close box

For various purposes, you might need to perform similar tracking on an arbitrary rectangle in a window. The function DoTrackRect defined in Listing 4-6 shows one way to define such a function.

Note
Venn Diagrammer calls DoTrackRect to handle mouse-down events in the tool icons. See Listing 6-9 beginning on page 121.
Listing 4-6 Tracking the cursor in an arbitrary rectangle

FUNCTION DoTrackRect (myWindow: WindowPtr; myRect: Rect): Boolean;
   VAR
      myIgnore:   LongInt;
      myPoint:    Point;
BEGIN
   InvertRect(myRect);           {invert the rectangle}
   REPEAT
      Delay(kVisualDelay, myIgnore)
   UNTIL NOT StillDown;          {until mouse is released}
   InvertRect(myRect);

   GetMouse(myPoint);            {get mouse location}
   DoTrackRect := PtInRect(myPoint, myRect);
END;
The DoTrackRect function inverts the specified rectangle and keeps it inverted until the user releases the mouse button. The Event Manager function StillDown looks in your application's event queue for a mouse-up event; if none is found, StillDown returns TRUE; otherwise, StillDown returns FALSE. Note that DoTrackRect loops until StillDown returns FALSE, indicating that the corresponding mouse-up event has been found. The call to the Delay procedure within the loop is to ensure that the rectangle is inverted for some minimum, user-perceptible amount of time.

CONST
   kVisualDelay         = 6;     {wait 6 ticks (one-tenth second)}
The DoTrackRect function loops until StillDown detects the appropriate mouse-up event and then returns the specified rectangle to its original state by inverting it again. Next, DoTrackRect calls the Event Manager function GetMouse to determine the current position of the cursor. If, when the mouse button is released, the cursor is still inside the specified rectangle (as determined by the QuickDraw routine PtInRect), then DoTrackRect returns TRUE.

As you can see, you sometimes want to call Event Manager routines from outside your main event loop, most often to monitor mouse movements and button states once the user has clicked in some particular part of a window.


Previous Book Contents Book Index Next

© Apple Computer, Inc.
9 JUL 1996